home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 6 / The Arsenal Files 6 (Arsenal Computer).ISO / prg_casm / struc.zip / STRUC.ASM < prev   
Assembly Source File  |  1996-02-02  |  5KB  |  128 lines

  1. ; I'll be using the extended  registers,  so  ".386"  is required here. I'm
  2. ;  using simplified directives here. However, there is no reason why that I 
  3. ;  can't declare my own segments. I  will  probably  give  a sample of that 
  4. ;  in a future upload or an appended version of this upload.
  5. .386
  6.  
  7. ;-----I'll be accessing extended memory  while  in  protected mode.  In that 
  8. ;      mode, memory is like one of  those  highways  across  the western U.S. 
  9. ;      deserts. Using the "C" calling convention eliminates the need for the
  10. ;      preceding underscores.
  11. .model flat, c
  12.  
  13. ;-----The assembler structure which makes it easy to manipulate data between 
  14. ;      the C++ module and here
  15. mystruct struc
  16. ascii_char     db   ?
  17. unsigned_char  db   ?
  18. short          dw   ?
  19. unsigned_short dw   ?
  20. long           dd   ?
  21. unsigned_long  dd   ?
  22. string         db   13, 10, "This is the string from the .asm routine", 0
  23.  
  24. mystruct ends
  25.  
  26. ;----- This will be the data segment. It is of course not segmented the
  27. ;       same as in real mode, but is defined that way.
  28. .data
  29.  
  30. struct_1 mystruct <,,,,,>
  31.  
  32. esp_save   dd  ?
  33. ss_save    dw  ?
  34. ebp_save   dd  ?
  35.  
  36. struct_ptr dd  ?
  37. ;----------------------------------------
  38.  
  39. ;----- Here is the declaration of the section where the code will begin.
  40. ;       variables can go here as well, however it is not normal, or keeping
  41. ;       in tradition to write to the code area (modify variables) while
  42. ;       operating in protected mode. 
  43. .code
  44.  
  45.  
  46. ;----- Since this routine will be "called" from the C++ module, it must of
  47. ;       course be made "public"
  48. public  fill_struct
  49.  
  50. ;----- all procedures  in  protected mode are of type "near". Something that
  51. ;       i've noticed when compiling using Power Pack is that "near" actually
  52. ;       has to  be  declared here. Whereas usually it will default to "near"
  53. ;       here  as  long  as  "near"  is declared at the end of the procedure.
  54. fill_struct proc  near 
  55.  
  56. ;----- This  is  the  argument  that  was passed to here from the C++ module
  57. ARG the_struct:dword
  58.  
  59. ;----- I have the most  success  saving  and  repositioning reference to the 
  60. ;       stack using this method. I often  prefer  to define a separate stack 
  61. ;       within  my assembler module. This  lays  the ground-work to do that.
  62. ;       I'll be showing how easy it is to do that, at a later date.
  63. mov  ebp_save, ebp
  64. mov  ss_save, ss
  65. mov  esp_save, esp
  66. mov  ebp, esp
  67.  
  68. ;----- This will  load  the  EBX register with the address of the  structure 
  69. ;       within the C++ module. This also makes it quite convenient to access 
  70. ;       character sequences of structured type. I'll also save this argument
  71. ;       just out of habit, so I  don't have to worry about finding it on the
  72. ;       stack if I need it later.
  73. mov  ebx, [the_struct]
  74. mov  [struct_ptr], ebx
  75.  
  76. ;----- The  following  code  will use  the offset values from my  assembler
  77. ;       routine  to  load  values  into the structure within the C++ module.
  78. mov [struct_1.unsigned_char], 255
  79. mov cl, [struct_1.unsigned_char]
  80.  
  81. ;----- Here  is the  actual  loading  of the structure within the C++ module. 
  82. ;       I can also, first  fill  my   structure here, with the data I desire, 
  83. ;       and then send a copy of that data to the C++ module. If you've  been 
  84. ;       following the code, you  may have noticed, setting up to do that was 
  85. ;       the little maneuver   that I  did  in  the two lines above. It would  
  86. ;       also  be  perfectly fine  to load default values within my structure,  
  87. ;       as is more commonly done.
  88. mov  [ebx].ascii_char, -'~'
  89. mov  [ebx].unsigned_char, cl  
  90. mov  [ebx].short, -32767
  91. mov  [ebx].unsigned_short, 65535
  92. mov  [ebx].long, -2147483647
  93. mov  [ebx].unsigned_long, 4294967295
  94.  
  95. ;----- This  is  the  code  used to  copy  our  string over to the allocated
  96. ;       array  within  the  C++ module. Note  that I've terminated the array
  97. ;       with 0, since I believe that to be  what the C++ print function will 
  98. ;       look for as a  terminator.  Also note that although the value  in CX 
  99. ;       can exceed the actual length of  the  string  from  this  module, it 
  100. ;       -MUST NOT-  exceed the  size  of the allocated  array within the C++ 
  101. ;       module. Also  note  that  even  though  I'm  only moving a byte at a 
  102. ;       time here, there is  no reason,  one  cannot  move 32 bits at a time.
  103. mov edx, offset struct_1.string 
  104. mov cx, 54
  105. cld
  106. repeat:
  107.  
  108. mov al, [edx]            
  109. mov  [ebx].string, al     
  110. inc edx
  111. inc bx
  112. dec cx
  113. cmp cx, 0
  114. jne repeat
  115.  
  116. ;----- Now we'll return the saved stack type registers.
  117. mov  esp, esp_save
  118. mov  ss, ss_save
  119. mov  ebp, ebp_save
  120.  
  121. ret
  122. fill_struct endp
  123.  
  124. ;----- That's all there is to it. Pretty easy don't  you think?
  125. ;      Now.... let's give Borland a round of applause for their  
  126. ;       Power Pack product!
  127. end
  128.